/**
 * 
 */
package com.thor.palmmall.rest.elecharges;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.List;

import com.google.common.collect.Lists;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.converters.Converter;
import com.thoughtworks.xstream.converters.MarshallingContext;
import com.thoughtworks.xstream.converters.UnmarshallingContext;
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
import com.thoughtworks.xstream.io.xml.DomDriver;

/**
 * @author NuoSa
 *
 * @since 1.0
 */
public class xmlToJavaBeanTest {

  public static class Result implements Serializable {
    private static final long serialVersionUID = 6630814968361291084L;

    private String userId;
    private String userName;
    private BigDecimal balance;
    private List<MeterComID> meterComIds = Lists.newArrayList();

    public String getUserId() {
      return userId;
    }

    public void setUserId(String userId) {
      this.userId = userId;
    }

    public String getUserName() {
      return userName;
    }

    public void setUserName(String userName) {
      this.userName = userName;
    }

    public BigDecimal getBalance() {
      return balance;
    }

    public void setBalance(BigDecimal balance) {
      this.balance = balance;
    }

    public List<MeterComID> getMeterComIds() {
      return meterComIds;
    }

    public void setMeterComIds(List<MeterComID> meterComIds) {
      this.meterComIds = meterComIds;
    }

  }

  public static class MeterComID implements Serializable {
    private static final long serialVersionUID = -2172865425311839299L;

    private String id;
    private String value;

    public String getId() {
      return id;
    }

    public void setId(String id) {
      this.id = id;
    }

    public String getValue() {
      return value;
    }

    public void setValue(String value) {
      this.value = value;
    }

  }

  public static void main(String[] args) {
    String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?><dataset>"
        + "<parameter name=\"USEID\">123456789</parameter>"
        + "<parameter name=\"USERNAME\">娴嬭瘯</parameter>"
        + "<parameter name=\"BALANCE\">0.00</parameter>"
        + "<parameter name=\"METERCOMID0\">000000000001</parameter>"
        + "<parameter name=\"VALUE0\">0.00</parameter>"
        + "<parameter name=\"METERCOMID1\">000000001122</parameter>"
        + "<parameter name=\"VALUE1\">103.00</parameter>" + "</dataset>";

    XStream xstream = new XStream(new DomDriver());
    xstream.alias("dataset", Result.class);

    xstream.registerConverter(new Converter() {

      @Override
      public boolean canConvert(Class type) {
        return Result.class.equals(type);
      }

      @Override
      public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
        Result r = new Result();

        while (reader.hasMoreChildren()) {
          reader.moveDown();
          String nodeName = reader.getNodeName();
          if (!"parameter".equals(nodeName)) {
            continue;
          }

          String attrName = reader.getAttribute("name");
          if ("USEID".equals(attrName)) {
            r.setUserId(reader.getValue());
          } else if ("USERNAME".equals(attrName)) {
            r.setUserName(reader.getValue());
          } else if ("BALANCE".equals(attrName)) {
            r.setBalance(reader.getValue() == null ? null : new BigDecimal(reader.getValue()));
          } else if (attrName.startsWith("METERCOMID")) {
            MeterComID mc = new MeterComID();
            mc.setId(reader.getValue());
            r.getMeterComIds().add(mc);
          } else if (attrName.startsWith("VALUE")) {
            int index = Integer.valueOf(attrName.substring("VALUE".length()));
            r.getMeterComIds().get(index).setValue(reader.getValue());
          }

          reader.moveUp();
        }

        return r;
      }

      @Override
      public void marshal(Object source, HierarchicalStreamWriter writer,
          MarshallingContext context) {
        // TODO Auto-generated method stub

      }
    });
    Result r = (Result) xstream.fromXML(xml);
    r.getUserId();
  }

}
